package util.parser.wikiXML;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import java.util.LinkedList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;
import util.wikiXML.objectModel.*;

;

public class AnchorExtractor extends DefaultHandler {

	/**
	 * @param args
	 */

	/**
	 * @param args
	 */

	private String tempVal;

	// to maintain context
	private WikiPage wiki;
	private WikiLink link;

	/*
	 * flags
	 */

	boolean crossLingualOn = false;

	boolean categoryOn = false;

	public AnchorExtractor() {
		wiki = null;
	}

	public void startDocument() {

		wiki = new WikiPage();

	}

	public WikiPage parseWiki(InputStream in) {

		// get a factory
		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {

			// get a new instance of parser
			SAXParser sp = spf.newSAXParser();

			// parse the file and also register this class for call backs
			sp.parse(in, this);

		} catch (SAXException se) {
			se.printStackTrace();
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (IOException ie) {
			ie.printStackTrace();
		}

		return wiki;
	}

	// Event Handlers
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {

		// we get page name and page id from meta tags
		if (qName.equalsIgnoreCase("meta")) {
			// add pagename and page id

			if (attributes.getValue("name").equalsIgnoreCase("wx_pagename")) {
				wiki.setName(attributes.getValue("content"));

			} else if (attributes.getValue("name").equalsIgnoreCase(
					"wx_page_id")) {

				wiki.setId(attributes.getValue("content"));
			}

		}

		/**
		 * We detect the start of the Category links section of the wikipage,
		 * where most of the content is located
		 */

		if (qName.equalsIgnoreCase("div")
				&& attributes.getValue("id").equalsIgnoreCase(
						"wx_categorylinks")) {
			categoryOn = true;

		}

		/**
		 * We detect the start of the Cross-lingual links section of the
		 * wikipage, where most of the content is located
		 */
		if (qName.equalsIgnoreCase("div")
				&& attributes.getValue("id").equalsIgnoreCase(
						"wx_languagelinks")) {
			crossLingualOn = true;

		}

		/**
		 * <a> anchor tags
		 * 
		 * We create a WikiLink object, feed it with the attributes of the <a>
		 * tag
		 * 
		 * if the paragraphOn flag is activated, we add the link to the list of
		 * elements of the currentParagraph object
		 */

		if (qName.equalsIgnoreCase("a")) {

			String tmp_field;
			link = new WikiLink();

			tmp_field = attributes.getValue("href");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setHref(tmp_field);
			}

			tmp_field = attributes.getValue("wx:linktype");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setType(tmp_field);
			}

			tmp_field = attributes.getValue("title");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setTitle(tmp_field);
			}

			tmp_field = attributes.getValue("wx:pagename");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setPageName(tmp_field);
			}

			tmp_field = attributes.getValue("wx:page_id");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setPageId(tmp_field);
			}

			tmp_field = attributes.getValue("id");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setId(tmp_field);
			}

			tmp_field = attributes.getValue("fragment");
			if (tmp_field != null && !tmp_field.equals("")) {
				link.setFragment(tmp_field);
			}

		//	System.out.println("Link:" + link.getTitle());

			wiki.links.add(link);

		}
		// reset
		tempVal = "";
	}

	public void characters(char[] ch, int start, int length)
			throws SAXException {
		tempVal = new String(ch, start, length);
	}

	public void endElement(String uri, String localName, String qName)
			throws SAXException {

		// we start the wikipage when we end parsing the title
		if (qName.equalsIgnoreCase("title")) {
			// add it to the list

			wiki = new WikiPage();
			wiki.setTitle(tempVal);

		}

		/**
		 * <a> tag
		 * 
		 * Extract text and add it to current link
		 * 
		 **/

		if (qName.equalsIgnoreCase("a")) {

			link.setText(tempVal);

		}

	}

	public static WikiPage parseWikiFile(FileInputStream in) {
		AnchorExtractor spe = new AnchorExtractor();

		WikiPage wiki = spe.parseWiki(in);
		spe = null;
		return wiki;

	}

	public static WikiPage parseWikiFile(InputStream in) {
		AnchorExtractor spe = new AnchorExtractor();

		WikiPage wiki = spe.parseWiki(in);
		spe = null;
		return wiki;

	}

	public static void main(String[] args) {
		AnchorExtractor spe = new AnchorExtractor();

		File file = new File(
				"/media/sata/data/wikipedia/en/wikixml-20080724/borreme/p161nnnnn/16187503.xml");
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		WikiPage wiki = spe.parseWiki(in);

		for (int i = 0; i < wiki.links.size(); i++) {

			System.out.println(wiki.links.get(i).getText() + "\t"
					+ wiki.links.get(i).getHref());

		}
		// System.out.println(wiki.getSectionText(0));

	}

}
